package com.carol.lmsbe.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.carol.lmsbe.dto.LaboratoryCreateRequest;
import com.carol.lmsbe.dto.LaboratoryDTO;
import com.carol.lmsbe.dto.LaboratoryQueryRequest;
import com.carol.lmsbe.dto.LaboratoryUpdateRequest;
import com.carol.lmsbe.entity.Laboratory;
import com.carol.lmsbe.mapper.LaboratoryMapper;
import com.carol.lmsbe.service.LaboratoryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 实验室服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LaboratoryServiceImpl implements LaboratoryService {

    private final LaboratoryMapper laboratoryMapper;

    @Override
    public Page<LaboratoryDTO> getLaboratoryList(LaboratoryQueryRequest request) {
        Page<Laboratory> page = new Page<>(request.getCurrent(), request.getSize());
        
        LambdaQueryWrapper<Laboratory> queryWrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(request.getName())) {
            queryWrapper.like(Laboratory::getName, request.getName());
        }
        if (StringUtils.hasText(request.getLocation())) {
            queryWrapper.like(Laboratory::getLocation, request.getLocation());
        }
        if (StringUtils.hasText(request.getManagerName())) {
            queryWrapper.like(Laboratory::getManagerName, request.getManagerName());
        }
        if (request.getStatus() != null) {
            queryWrapper.eq(Laboratory::getStatus, request.getStatus());
        }
        
        queryWrapper.orderByDesc(Laboratory::getCreateTime);
        
        Page<Laboratory> laboratoryPage = laboratoryMapper.selectPage(page, queryWrapper);
        
        // 转换为DTO
        Page<LaboratoryDTO> dtoPage = new Page<>();
        BeanUtils.copyProperties(laboratoryPage, dtoPage, "records");
        dtoPage.setRecords(laboratoryPage.getRecords().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList()));
        
        return dtoPage;
    }

    @Override
    public LaboratoryDTO getLaboratoryById(Long id) {
        Laboratory laboratory = laboratoryMapper.selectById(id);
        if (laboratory == null) {
            throw new RuntimeException("实验室不存在");
        }
        return convertToDTO(laboratory);
    }

    @Override
    @Transactional
    public LaboratoryDTO createLaboratory(LaboratoryCreateRequest request) {
        // 检查实验室名称是否已存在
        LambdaQueryWrapper<Laboratory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Laboratory::getName, request.getName());
        Laboratory existingLaboratory = laboratoryMapper.selectOne(queryWrapper);
        if (existingLaboratory != null) {
            throw new RuntimeException("实验室名称已存在");
        }
        
        Laboratory laboratory = new Laboratory();
        BeanUtils.copyProperties(request, laboratory);
        
        laboratoryMapper.insert(laboratory);
        
        return convertToDTO(laboratory);
    }

    @Override
    @Transactional
    public LaboratoryDTO updateLaboratory(LaboratoryUpdateRequest request) {
        Laboratory laboratory = laboratoryMapper.selectById(request.getId());
        if (laboratory == null) {
            throw new RuntimeException("实验室不存在");
        }
        
        // 检查实验室名称是否已被其他实验室使用
        LambdaQueryWrapper<Laboratory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Laboratory::getName, request.getName())
                .ne(Laboratory::getId, request.getId());
        Laboratory existingLaboratory = laboratoryMapper.selectOne(queryWrapper);
        if (existingLaboratory != null) {
            throw new RuntimeException("实验室名称已存在");
        }
        
        BeanUtils.copyProperties(request, laboratory);
        laboratoryMapper.updateById(laboratory);
        
        return convertToDTO(laboratory);
    }

    @Override
    @Transactional
    public void deleteLaboratory(Long id) {
        Laboratory laboratory = laboratoryMapper.selectById(id);
        if (laboratory == null) {
            throw new RuntimeException("实验室不存在");
        }
        
        // 检查是否有用户关联此实验室
        // 这里可以添加检查逻辑，如果有用户关联则不允许删除
        
        laboratoryMapper.deleteById(id);
    }

    @Override
    public List<LaboratoryDTO> getAllActiveLaboratories() {
        List<Laboratory> laboratories = laboratoryMapper.selectAllActive();
        return laboratories.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 转换为DTO
     */
    private LaboratoryDTO convertToDTO(Laboratory laboratory) {
        LaboratoryDTO dto = new LaboratoryDTO();
        BeanUtils.copyProperties(laboratory, dto);
        
        // 设置状态文本
        if (laboratory.getStatus() != null) {
            switch (laboratory.getStatus()) {
                case 1:
                    dto.setStatusText("启用");
                    break;
                case 0:
                    dto.setStatusText("禁用");
                    break;
                default:
                    dto.setStatusText("未知");
                    break;
            }
        }
        
        return dto;
    }
}
